home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
send.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
27KB
|
1,189 lines
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mutt.h"
#include "mutt_curses.h"
#include "keymap.h"
#include "send.h"
#include "mime.h"
#include "mailbox.h"
#include "copy.h"
#include "state.h"
#include "parse.h"
#include "mx.h"
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#ifdef _PGPPATH
#include "pgp.h"
#endif
FILE *mutt_open_read (const char *path, pid_t *thepid)
{
FILE *f;
int len = strlen (path);
if (path[len-1] == '|')
{
/* read from a pipe */
char *s = safe_strdup (path);
s[len-1] = 0;
endwin ();
*thepid = mutt_create_filter (s, NULL, &f, NULL);
free (s);
}
else
{
f = fopen (path, "r");
*thepid = -1;
}
return (f);
}
static void append_signature (ENVELOPE *env, FILE *f)
{
FILE *tmpfp;
pid_t thepid;
if ((tmpfp = mutt_open_read (Signature, &thepid)))
{
if (option (OPTSIGDASHES))
fputs ("\n-- \n", f);
mutt_copy_stream (tmpfp, f);
fclose (tmpfp);
if (thepid != -1)
mutt_wait_filter (thepid);
}
}
/* compare two e-mail addresses and return 1 if they are equivalent */
static int mutt_addrcmp (ADDRESS *a, ADDRESS *b)
{
if (!a->mailbox || !b->mailbox)
return 0;
if (strcasecmp (a->mailbox, b->mailbox))
return 0;
if (!a->host || !b->host)
{
if (!a->host && !b->host)
return 1;
else
return 0;
}
if (strcasecmp (a->host, b->host))
return 0;
return 1;
}
/* search an e-mail address in a list */
static int mutt_addrsrc (ADDRESS *a, ADDRESS *lst)
{
for (; lst; lst = lst->next)
{
if (mutt_addrcmp (a, lst))
return (1);
}
return (0);
}
/* removes addresses from "b" which are contained in "a" */
static ADDRESS *mutt_remove_xrefs (ADDRESS *a, ADDRESS *b)
{
ADDRESS *top, *p, *prev = NULL;
top = b;
while (b)
{
p = a;
while (p)
{
if (mutt_addrcmp (p, b))
break;
p = p->next;
}
if (p)
{
if (prev)
{
prev->next = b->next;
b->next = NULL;
mutt_free_address (&b);
b = prev;
}
else
{
top = top->next;
b->next = NULL;
mutt_free_address (&b);
b = top;
}
}
else
{
prev = b;
b = b->next;
}
}
return top;
}
/* remove any address which matches the current user. if `leave_only' is
* nonzero, don't remove the user's address if it is the only one in the list
*/
static ADDRESS *remove_user (ADDRESS *a, int leave_only)
{
ADDRESS *top = NULL, *last = NULL;
while (a)
{
if (!mutt_addr_is_user (a))
{
if (top)
{
last->next = a;
last = last->next;
}
else
last = top = a;
a = a->next;
last->next = NULL;
}
else
{
ADDRESS *tmp = a;
a = a->next;
if (!leave_only || (a && a->next) || last)
{
tmp->next = NULL;
mutt_free_address (&tmp);
}
}
}
return top;
}
static ADDRESS *find_mailing_lists (ADDRESS *t, ADDRESS *c)
{
ADDRESS *top = NULL, *ptr = NULL, *tmp;
for (; t || c; t = c, c = NULL)
{
for (; t; t = t->next)
{
if (mutt_is_mail_list (t))
{
/* rfc822_cpy_adr() copies the whole list, not just one element, so
* temporarily cut the list.
*/
tmp = t->next;
t->next = NULL;
if (top)
{
ptr->next = rfc822_cpy_adr (t);
ptr = ptr->next;
}
else
ptr = top = rfc822_cpy_adr (t);
t->next = tmp; /* restore list */
}
}
}
return top;
}
static int edit_envelope (ENVELOPE *en)
{
char buf[HUGE_STRING];
buf[0] = 0;
rfc822_write_address (buf, sizeof (buf), en->to);
if (mutt_get_field ("To: ", buf, sizeof (buf), M_ALIAS) != 0 || !buf[0])
return (-1);
mutt_free_address (&en->to);
mutt_parse_adrlist (&en->to, buf, "@");
en->to = mutt_expand_aliases (en->to);
if (option (OPTASKCC))
{
buf[0] = 0;
rfc822_write_address (buf, sizeof (buf), en->cc);
if (mutt_get_field ("Cc: ", buf, sizeof (buf), M_ALIAS) != 0)
return (-1);
mutt_free_address (&en->cc);
mutt_parse_adrlist (&en->cc, buf, "@");
en->cc = mutt_expand_aliases (en->cc);
}
if (option (OPTASKBCC))
{
buf[0] = 0;
rfc822_write_address (buf, sizeof (buf), en->bcc);
if (mutt_get_field ("Bcc: ", buf, sizeof (buf), M_ALIAS) != 0)
return (-1);
mutt_free_address (&en->bcc);
mutt_parse_adrlist (&en->bcc, buf, "@");
en->bcc = mutt_expand_aliases (en->bcc);
}
if (en->subject)
{
if (option (OPTFASTREPLY))
return (0);
else
strfcpy (buf, en->subject, sizeof (buf));
}
else
buf[0] = 0;
if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) != 0 ||
(!buf[0] && query_quadoption (OPT_SUBJECT, "No subject, abort?") != 0))
{
mutt_message ("No subject, aborting.");
return (-1);
}
safe_free ((void **) &en->subject);
en->subject = safe_strdup (buf);
return 0;
}
static void process_user_recips (ENVELOPE *env)
{
LIST *uh = UserHeader;
for (; uh; uh = uh->next)
{
if (strncasecmp ("to:", uh->data, 3) == 0)
rfc822_parse_adrlist (&env->to, uh->data + 3, "@");
else if (strncasecmp ("cc:", uh->data, 3) == 0)
rfc822_parse_adrlist (&env->cc, uh->data + 3, "@");
else if (strncasecmp ("bcc:", uh->data, 4) == 0)
rfc822_parse_adrlist (&env->bcc, uh->data + 4, "@");
}
}
static void process_user_header (ENVELOPE *env)
{
LIST *uh = UserHeader;
LIST *last = env->userhdrs;
if (last)
while (last->next)
last = last->next;
for (; uh; uh = uh->next)
{
if (strncasecmp ("from:", uh->data, 5) == 0)
{
/* User has specified a default From: address. Get rid of the
* default address.
*/
mutt_free_address (&env->from);
rfc822_parse_adrlist (&env->from, uh->data + 5, "@");
}
else if (strncasecmp ("reply-to:", uh->data, 9) == 0)
{
mutt_free_address (&env->reply_to);
rfc822_parse_adrlist (&env->reply_to, uh->data + 9, "@");
}
else if (strncasecmp ("to:", uh->data, 3) != 0 &&
strncasecmp ("cc:", uh->data, 3) != 0 &&
strncasecmp ("bcc:", uh->data, 4) != 0)
{
if (last)
{
last->next = mutt_new_list ();
last = last->next;
}
else
last = env->userhdrs = mutt_new_list ();
last->data = safe_strdup (uh->data);
}
}
}
LIST *mutt_copy_list (LIST *p)
{
LIST *t, *r=NULL, *l=NULL;
for (; p; p = p->next)
{
t = (LIST *) safe_malloc (sizeof (LIST));
t->data = safe_strdup (p->data);
t->next = NULL;
if (l)
{
r->next = t;
r = r->next;
}
else
l = r = t;
}
return (l);
}
/* include a message as a reply or forward */
static int include_message (HEADER *cur, FILE *out, int forward)
{
char buffer[STRING];
int flags = 0;
#ifdef _PGPPATH
if (cur->pgp)
{
if (cur->pgp == PGPENCRYPT)
{
/* make sure we have the user's passphrase before proceeding... */
pgp_valid_passphrase ();
}
}
#endif /* _PGPPATH */
if (forward)
{
fputs ("----- Forwarded message from ", out);
buffer[0] = 0;
rfc822_write_address (buffer, sizeof (buffer), cur->env->from);
fputs (buffer, out);
fputs (" -----\n", out);
}
else if (Attribution[0])
{
mutt_make_string (buffer, sizeof (buffer), Attribution, cur);
fputs (buffer, out);
fputc ('\n', out);